/*
* Copyright 2011 Pavel Kozhin 
*
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
* http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed  under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License.
*
* Author: Pavel Kozhin.
*/
package org.etherframework.mediation
{
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.errors.IllegalOperationError;
	import flash.events.Event;
	import flash.geom.Matrix;
	import flash.utils.setTimeout;
	
	import mx.events.FlexEvent;
	import mx.preloaders.SparkDownloadProgressBar;

	public class EtherPreloader extends SparkDownloadProgressBar
	{
		protected var _barWidth:Number;
		protected var _barSprite:Sprite;
		protected var _downloadComplete:Boolean = false;
		protected var _preloader:Sprite;
		
		private var _childrenCreated:Boolean = false;
		
		override public function set preloader(value:Sprite):void
		{
			if (!value)
				throw new ArgumentError("Argument value:Sprite can not be null.");
			
			_preloader = value;
			
			// Added listeners to interrupt normal application initialization.
			// When it's interrupted we can add additional phase of progress.
			value.addEventListener(Event.COMPLETE, preloadCompleteHandler, 
				false, int.MAX_VALUE);
			value.addEventListener(FlexEvent.INIT_PROGRESS, 
				preloaderInitProgressHandler, false, int.MAX_VALUE);
			
			super.preloader = value;
		}
		
		protected function startProgressPhase():void
		{
			throw new IllegalOperationError("This method should be overridden by a subclass.");
		}
		
		protected function completeProgressPhase():void
		{
			_preloader.removeEventListener(Event.COMPLETE, preloadCompleteHandler);
			_preloader.removeEventListener(FlexEvent.INIT_PROGRESS, preloaderInitProgressHandler);
			
			// These events should be dispatched to continue 
			// normal application initialization.
			_preloader.dispatchEvent(new Event(Event.COMPLETE));
			_preloader.dispatchEvent(new FlexEvent(FlexEvent.INIT_PROGRESS));
		}
		
		protected function setProgress(completed:Number, total:Number):void
		{
			const highlightColors:Array = [0xFFFFFF, 0xEAEAEA];
			const fillColors:Array = [0xFFFFFF, 0xD8D8D8];
			const alphas:Array = [1, 1];
			const ratios:Array = [0, 255];
			
			var w:Number = Math.round(_barWidth * Math.min(completed / total, 1));
			var h:Number = 9;
			var g:Graphics = _barSprite.graphics;
			var m:Matrix = new Matrix();
			
			m.createGradientBox(w - 6, h - 2, 90, 2, 2);
			
			g.clear();
			
			g.lineStyle(1, 0x000000);
			g.lineGradientStyle("linear", highlightColors, alphas, ratios, m);
			g.beginGradientFill("linear", fillColors, alphas, ratios, m);
			g.drawRect(2, 2, w - 4, h - 4);
			g.endFill();
			
			g.lineStyle(1, 0, 0.55);
			g.moveTo(w - 1, 2);
			g.lineTo(w - 1, h - 1);
		}
		
		override protected function createChildren():void
		{
			if (_childrenCreated)
				throw new IllegalOperationError("Children are already created.");
			
			super.createChildren();
			
			_childrenCreated = true;
			_barWidth = Math.min(stageWidth - 10, 207) - 10;
			_barSprite = getChildAt(2) as Sprite;
		}
		
		override protected function setDownloadProgress(completed:Number, total:Number):void
		{
			super.setDownloadProgress(completed, total);
			
			if (completed == total)
				_downloadComplete = true;
		}
		
		private function preloaderInitProgressHandler(event:FlexEvent):void
		{
			event.stopImmediatePropagation();
			
			if (!_downloadComplete)
				setDownloadProgress(100, 100);
		}
		
		private function preloadCompleteHandler(event:Event):void
		{
			event.stopImmediatePropagation();
			
			if (!_childrenCreated)
				visible = true;
			
			setTimeout(startProgressPhase, 1000);
		}
	}
}